#include <Ecore.h>
#include <Ecore_Evas.h>
#include <Ecore_X.h>
#include <Edje.h>
#include <Evas.h>

#include <gst/gst.h>

#include <fcntl.h>
#include <pthread.h>
#include <string.h>
#include <unistd.h>

#include "v4l2_smart.h"

#define DEFAULT_WIDTH  640
#define DEFAULT_HEIGHT 480

typedef struct _Main_Data Main_Data;

struct _Main_Data
{
   Ecore_Evas *ecore_evas;
   Evas *evas;
   Evas_Object *obj;
};

static int
_main_signal_exit_cb(void *data, int ev_type, void *main_data)
{
   ecore_main_loop_quit();
   return 0;
}

static void
_main_delete_request_cb(Ecore_Evas *ee)
{
   ecore_main_loop_quit();
}

static void
_start_prewiew_cb(Main_Data *main_data, Evas_Object *im)
{
   Evas_Object *obj;
   int iw, ih, ow, oh;
   Evas_Colorspace icspace, ocspace;

   obj = main_data->obj;

   evas_object_image_pixels_dirty_set(im, 1);

   evas_object_image_size_get(im, &iw, &ih);
   v4l2_object_size_get(obj, &ow, &oh);
   icspace = evas_object_image_colorspace_get(im);
   ocspace = v4l2_object_colorspace_get(obj);
   if (icspace != ocspace)
     evas_object_image_colorspace_set(im, ocspace);
   if ((iw != ow) || (ih != oh))
     evas_object_image_size_set(im, ow, oh);
   evas_object_image_data_copy_set(im, v4l2_object_data_get(obj));

   evas_object_image_pixels_dirty_set(im, 0);
}

static void
_start_prewiew_1_cb(void *data, Evas_Object *frame, const char *emission, const char *source)
{
   Evas_Object *im;
   im = edje_object_part_swallow_get(frame, "swallow.content.preview_1");
   _start_prewiew_cb(data, im);
}

static void
_start_prewiew_2_cb(void *data, Evas_Object *frame, const char *emission, const char *source)
{
   Evas_Object *im;
   im = edje_object_part_swallow_get(frame, "swallow.content.preview_2");
   _start_prewiew_cb(data, im);
}

int main(int argc, char* argv[])
{
   Main_Data *main_data;
   Ecore_Evas *ecore_evas;
   Evas *evas;
   Evas_Object *obj;
   Evas_Object *preview_1;
   Evas_Object *preview_2;
   Evas_Object *frame;
   int w, h;

   gst_init(&argc, &argv);
   ecore_init();
   ecore_app_args_set(argc, (const char **)argv);
   ecore_event_handler_add(ECORE_EVENT_SIGNAL_EXIT, _main_signal_exit_cb, NULL);
   ecore_evas_init();
   edje_init();

   main_data = calloc(1, sizeof(Main_Data));

#ifdef RGB565_A5P
   ecore_evas = ecore_evas_software_x11_16_new(NULL, 0, 0, 0, 800, 480);
#elif ARGB8888
   ecore_evas = ecore_evas_software_x11_new(NULL, 0, 0, 0, 800, 480);
#else
   ecore_evas = ecore_evas_software_x11_new(NULL, 0, 0, 0, 800, 480);
#endif

   ecore_evas_callback_delete_request_set(ecore_evas, _main_delete_request_cb);
   ecore_evas_title_set(ecore_evas, "Evas v4l2 Test Program");
   ecore_evas_name_class_set(ecore_evas, "evas_v4l2_test", "main");
   ecore_evas_show(ecore_evas);
   main_data->ecore_evas = ecore_evas;

   evas = ecore_evas_get(ecore_evas);
   evas_image_cache_set(evas, 8 * 1024 * 1024);
   main_data->evas = evas;

   obj = v4l2_object_add(evas);
   evas_object_move(obj, 0, 0);
   evas_object_resize(obj, DEFAULT_WIDTH, DEFAULT_HEIGHT);
   evas_object_layer_set(obj, -999);
   evas_object_show(obj);
   evas_object_focus_set(obj, 1);
#ifdef RGB565_A5P
   v4l2_object_colorspace_set(obj, EVAS_COLORSPACE_RGB565_A5P);
#elif ARGB8888
   v4l2_object_colorspace_set(obj, EVAS_COLORSPACE_ARGB8888);
#else
   v4l2_object_colorspace_set(obj, EVAS_COLORSPACE_YCBCR422P601_PL);
#endif
   main_data->obj = obj;

   preview_1 = evas_object_image_add(evas);
   evas_object_move(preview_1, 0, 0);
   evas_object_resize(preview_1, DEFAULT_WIDTH, DEFAULT_HEIGHT);
   evas_object_layer_set(preview_1, -999);
   evas_object_show(preview_1);
   evas_object_image_alpha_set(preview_1, 0);
   evas_object_image_fill_set(preview_1, 0, 0, DEFAULT_WIDTH, DEFAULT_HEIGHT);

   preview_2 = evas_object_image_add(evas);
   evas_object_move(preview_2, 0, 0);
   evas_object_resize(preview_2, DEFAULT_WIDTH, DEFAULT_HEIGHT);
   evas_object_layer_set(preview_2, -999);
   evas_object_show(preview_2);
   evas_object_image_alpha_set(preview_2, 0);
   evas_object_image_fill_set(preview_2, 0, 0, DEFAULT_WIDTH, DEFAULT_HEIGHT);

   frame = edje_object_add(evas);
   edje_object_file_set(frame, "theme.edj", "frame");
   edje_extern_object_min_size_set(obj, DEFAULT_WIDTH, DEFAULT_HEIGHT);
   edje_object_part_swallow(frame, "swallow.content", obj);
   edje_object_part_swallow(frame, "swallow.content.preview_1", preview_1);
   edje_object_part_swallow(frame, "swallow.content.preview_2", preview_2);
   edje_object_size_min_calc(frame, &w, &h);
   evas_object_move(frame, 0, 0);
   evas_object_resize(frame, w, h);
   edje_object_signal_callback_add(frame, "start_preview_1", "*", _start_prewiew_1_cb, main_data);
   edje_object_signal_callback_add(frame, "start_preview_2", "*", _start_prewiew_2_cb, main_data);
   evas_object_show(frame);

   v4l2_object_play_set(main_data->obj, 1);

   ecore_main_loop_begin();

   v4l2_object_play_set(main_data->obj, 0);
   evas_object_del(obj);
   evas_object_del(preview_1);
   evas_object_del(preview_2);
   evas_object_del(frame);
   free(main_data);

   return 0;
}
